<?php

/**
 * User Hook helps create page view.
 *
 * PHP versions 5
 * CAKEPHP versions 2.x
 * 
 * Green CMS - Content Management System and Framework Powerfull by Cakephp
 * Copyright 2012, GREEN GLOBAL CO., LTD (toancauxanh.vn)
 * 
 * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
 * Copyright 2005-2011, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @author        Technology Lab No.I <tech1@toancauxanh.vn>
 * @link          
 * @package       Node.Helper
 * @since         Green v 1.0
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */
class MenuHelper extends AppHelper {

    /**
     * Format to attribute
     *
     * @var string
     */
    protected $_attributeFormat = '%s="%s"';

    /**
     * Tree menu generation default settings.
     *
     * ## Settings: 
     *
     *  -       `id`: Optional string for the id attribute of top level tag. (default - none)
     *  -       `force`: Forced rendering. Items with `status` = 0 will be rendered, as well childs of parents with `expanded` = false.
     *  -	`fields`: The fields to use to identify a user by
     *  -	`class`: 
     *             + `root` : Optional array of CSS classes for top level tag.
     *             + `old` : If it is set to true then odd classname will be provided with each item. (default - null)
     *             + `even` : If it is set to true then even classname will be provided with each item. (default - null)
     *             + `identity` : Optional string CSS classes identity of menu.
     *             + `index` : Optional string of CSS classes index for item.
     *             + `active` : Classname for the selected/current item. (default - 'selected')
     *             + `first` : Classname for the first item. (default - 'first-item')
     *             + `last` : Classname for the last item. (default - 'last-item')
     *             + `expand` : Classname for the expand item. (default - 'expanded')
     *             + `collapse` : Classname for the collapse item. (default - 'collapsed')
     *  -       `tags` : 
     *             + `parent` if you want to use other tag than ul for menu items container. (default - '<ul %s>%s</ul>')
     *             + `item` If you want to use other tag than li for menu items. (default - '<li %s>%s</li>')
     *  -        `itemAttributes`   : Mixed array list of html attributes for the item tag. (default - none)
     *  -        `parentAttributes` : Mixed array list of html attributes for the parent tag. (default - none)
     *  -        `handler` : Callback handler to use to change menu contents and attributes.
     *
     * @var array
     */
    protected $settings = array(
        'id' => null,
        'force' => false,
        'fields' => array(
            'id' => 'id',
            'title' => 'title',
            'path' => 'path',
            'target' => 'target',
            'description' => 'description',
            'expanded' => 'expanded',
            'selected' => 'selected'
        ),
        'class' => array(
            'root' => null,
            'old' => null,
            'even' => null,
            'identity' => 'menu-',
            'index' => 'menu-item-',
            'active' => 'selected',
            'first' => 'first',
            'last' => 'last',
            'expand' => 'expanded',
            'collapse' => 'collapsed',
        ),
        'tags' => array(
            'item' => '<li %s>%s</li>',
            'parent' => '<ul %s>%s</ul>'
        ),
        'itemAttributes' => array(),
        'parentAttributes' => array('class' => 'menu'),
        'handler' => null,
    );

    /**
     * Runtime settings
     *
     * @var array
     */
    protected $_runtime = array();

    /**
     * Block Hook
     *
     * @param array $block
     * @param array $params
     * @param array $options
     * 
     * @return void
     */
    public function block($block, $params, $options = array()) {
        $block['content'] = $this->load($block['delta'], $params);
    }

    /**
     * Tree menu generation method.
     *
     * @param string $id the id of menu
     * @param array $settings
     * @return string HTML representation of the passed data
     */
    public function load($id, $settings = array()) {
        $Model = ClassRegistry::init('Menu.MenuLink');
        $items = $Model->find('threaded', array(
            'locale' => true,
            'fields' => array(
                'title', 'description', 'path', 'parent_id', 'target', 'selected', 'expanded'
            ),
            'order' => array('MenuLink.rght' => 'ASC'),
            'conditions' => array(
                'enabled' => true,
                'MenuLink.menu_id' => $id)));

        if (empty($items)) {
            return '';
        }
        return $this->generate($items, array_merge($settings, array('id' => $id)));
    }

    /**
     * Tree menu generation method and change runtime settings.
     *
     * It accepts only results of `Model::find('threaded')`.
     * 
     * @param array $items data to loop on
     * @param array runtime $settings
     * @see MenuHelper::settings
     * @return string HTML representation of the passed data
     */
    public function generate($items, $settings = array()) {
        $this->_runtime = Set::merge($this->settings, $settings);
        if ($this->_runtime['handler'] && !is_callable($this->_runtime['handler'])) {
            $this->_runtime['handler'] = null;
            trigger_error(__d('debug', 'You must give a handler callback in menu settings.'), E_USER_ERROR);
        }
        $output = $this->_generate($items);
        $this->_runtime = null;
        return $output;
    }

    /**
     * Get runtime settings in current generate menu.
     *
     * @param string $key the key of config, null to get all runtime settings
     * @return mixed
     */
    public function runtime($key = null) {
        if (is_null($key)) {
            return $this->_runtime;
        }
        if (isset($this->_runtime[$key])) {
            return $this->_runtime[$key];
        }
        return null;
    }

    /**
     * Tree menu generation method.
     *
     * It accepts only results of `Model::find('threaded')`.
     * 
     * @param array $items data to loop on
     * @param integer $level the level of menu
     * @return string HTML representation of the passed data
     */
    protected function _generate($items, $level = 0) {
        $items = $this->_buildItem($items, $level);
        $attributes = $this->_runtime['parentAttributes'];
        if ($level === 0) {
            if (!isset($attributes['class'])) {
                $attributes['class'] = array();
            }
            $attributes['class'] = (array) $attributes['class'];
            if ($this->_runtime['id']) {
                $attributes['class'][] = $this->_runtime['class']['identity'] . $this->_runtime['id'];
            }
            if ($this->_runtime['class']['root']) {
                $attributes['class'][] = $this->_runtime['class']['root'];
            }
        }
        return sprintf($this->_runtime['tags']['parent'], $this->_parseAttributes($attributes, null, ' ', ''), $items);
    }

    /**
     * Tree menu items builder.
     *
     * @param array $items data to loop on
     * @param integer $level the level of menu
     * @return string HTML representation of the passed data
     */
    protected function _buildItem($items, $level) {
        $output = '';
        $index = 1;
        $count = count($items);
        $fields = $this->_runtime['fields'];
        foreach ($items as $data) {
            $item = array_shift($data);

            //@todo dispath event  $item
            //@todo Check permissions

            $options = array('escape' => false, 'class' => null);
            if ($this->_runtime['handler']) {
                if (call_user_func($this->_runtime['handler'], &$item, &$options, ($fields)) === false) {
                    continue;
                }
            }
            
            if (empty($item[$fields['path']])) {
                $item[$fields['path']] = '#';
            }

            $classNames = array();
            if (isset($item[$fields['id']]) && $this->_runtime['class']['index']) {
                $classNames[] = $this->_runtime['class']['index'] . $item[$fields['id']];
            }
            if (!empty($this->_runtime['itemAttributes']['class'])) {
                $classNames[] = $this->_runtime['itemAttributes']['class'];
            }
            if ($this->_runtime['class']['first'] && $index === 1) {
                $classNames[] = $this->_runtime['class']['first'];
            }

            if ($this->_runtime['class']['last'] && $index >= $count) {
                $classNames[] = $this->_runtime['class']['last'];
            }
            
            $options['class'] = (array) $options['class'];
            if ($this->_runtime['class']['active'] && !empty($item[$fields['selected']])
                    && Router::match($item[$fields['selected']], $this->request)) {
                $classNames[] = $options['class'][] = $this->_runtime['class']['active'];
            }

            if (!empty($item[$fields['target']])) {
                $options['target'] = $item[$fields['target']];
            }
            if (isset($item[$fields['description']])) {
                $options['title'] = $item[$fields['description']];
            }
            $_output = $this->_View->Html->link($item[$fields['title']], $item[$fields['path']], $options);

            if (!empty($data['children']) && (!empty($item[$fields['expanded']]) || $this->_runtime['force'])) {
                if ($this->_runtime['class']['expand']) {
                    $classNames[] = $this->_runtime['class']['expand'];
                }
                $_output .= $this->_generate($data['children'], $level + 1);
            } elseif (!empty($data['children']) && $this->_runtime['class']['collapse']) {
                $classNames[] = $this->_runtime['class']['collapse'];
            }

            if ($this->_runtime['class']['even'] && $index % 2 == 0) {
                $classNames[] = $this->_runtime['class']['even'];
            } elseif ($this->_runtime['class']['old'] && $index % 2 != 0) {
                $classNames[] = $this->_runtime['class']['old'];
            }

            $output .= sprintf($this->_runtime['tags']['item'], $this->_parseAttributes(array_merge($this->_runtime['itemAttributes'], array(
                                'class' => $classNames)), array(), ' ', '', true), $_output);
            $index++;
        }
        return $output;
    }

    /**
     * Returns a list of events this object is implementing, when the class is registered
     * in an event manager, each individual method will be associated to the respective event.
     *
     * @return array associative array or event key names pointing to the function
     * that should be called in the object when the respective event is fired
     */
    public function implementedEvents() {
        return array(
            'Helper.Layout.Menu.block' => 'block'
        );
    }
    //active top link menu
    function activeTopLink($path, $thisHere){
        $thisHere= substr($thisHere, 0);
           //debug($thisHere);
        $params= $this->params;
        $action= $params['action'];
         $current="";
        
        if($path===$thisHere){
            $current= "wd-current";
          
        }
        return $current;
    }
    function activeMainLinkAdmin($path, $thisHere){     
        $thisHere= substr($thisHere, 0);                   
        $params= $this->params;        
        $action= $params['action'];
         $current=""; 
                
        if($path===$thisHere){                    
            $current= "active";
          
        }       
        return $current;
    } 
    //active main link menu
    function activeMainLink($path, $thisHere){
        $thisHere= substr($thisHere, 0);       
        $params= $this->params;
        $action= $params['action'];
         $current="";
        
        if($path===$thisHere){
            $current= "active";
          
        }
        return $current;
    }    //active main link menu
    //active main link menu
    function activeMain($action=null, $id=null){        
        $actionCurrent = -1;
        $idCurrent = -1;
        $current = null;
        $actionCurrent = $this->request['action'];        
        if(!empty($this->request['pass'][0])){
            $idCurrent = $this->request['pass'][0];   
        }                                
        if((strcmp($action,$actionCurrent)==0)&&(strcmp($id,$idCurrent)==0)){
            $current= "wd-active";            
        }        
        //debug($actionCurrent);exit;               
        return $current;
    }
    function activeSimple($action){
        $actionCurrent = -1;  
        $current = null;
        $actionCurrent = $this->request['action'];        
        if(strcmp($actionCurrent,$action)==0)
        {
            $current= "wd-active";
        }
        return $current;       
    }

}
